/*
 * Copyright (c) 2022, IMMORTA Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright notice, this
 *   list of conditions and the following disclaimer in the documentation and/or
 *   other materials provided with the distribution.
 *
 * - Neither the name of IMMORTA Inc. nor the names of its
 *   contributors may be used to endorse or promote products derived from this
 *   software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef CMP_REG_ACCESS_H
#define CMP_REG_ACCESS_H

/*!
 * @file cmp_reg_access.h
 * @brief This file declares or defines cmp register access functions
 */

/*******Includes***************************************************************/
#include "cmp_drv.h"

/*******Definitions************************************************************/
#define CMP_LOOP_SEQUENCE_Msk       (0x1FF0000U)
#define CMP_LOOP_SEQUENCE_Pos       (16U)

#define CMP_C3_PRESET_Msk           (0x3FFU)
#define CMP_C3_PRESET_Pos           (0U)

#define CMP_DR_LMCHO_Msk            (0x1FFU)
#define CMP_DR_LMCHO_Pos            (0U)

#define CMP_SR_IRQFLAG_Msk          (0x3FFU)
#define CMP_SR_IRQFLAG_Pos          (0U)

#define CMP_C0_EDGETYPE(x)          (((uint32_t)(((uint32_t)(x)) << CMP_C0_EDGETYPE_Pos)) & CMP_C0_EDGETYPE_Msk)
#define CMP_C6_FILTERDIV(x)         (((uint32_t)(((uint32_t)(x)) << CMP_C6_FILTERDIV_Pos)) & CMP_C6_FILTERDIV_Msk)
#define CMP_C6_FILTERWIDTH(x)       (((uint32_t)(((uint32_t)(x)) << CMP_C6_FILTERWIDTH_Pos)) & CMP_C6_FILTERWIDTH_Msk)
#define CMP_C0_HYSTSEL(x)           (((uint32_t)(((uint32_t)(x)) << CMP_C0_HYSTSEL_Pos)) & CMP_C0_HYSTSEL_Msk)
#define CMP_C1_MODE(x)              (((uint32_t)(((uint32_t)(x)) << CMP_C1_MODE_Pos)) & CMP_C1_MODE_Msk)
#define CMP_C1_INNSEL(x)            (((uint32_t)(((uint32_t)(x)) << CMP_C1_INNSEL_Pos)) & CMP_C1_INNSEL_Msk)
#define CMP_C1_INPSEL(x)            (((uint32_t)(((uint32_t)(x)) << CMP_C1_INPSEL_Pos)) & CMP_C1_INPSEL_Msk)
#define CMP_C1_LOOPCH(x)            (((uint32_t)(((uint32_t)(x)) << CMP_LOOP_SEQUENCE_Pos)) & CMP_LOOP_SEQUENCE_Msk)
#define CMP_C2_LMSCNT(x)            (((uint32_t)(((uint32_t)(x)) << CMP_C2_LMSCNT_Pos)) & CMP_C2_LMSCNT_Msk)
#define CMP_C2_STABTIME(x)          (((uint32_t)(((uint32_t)(x)) << CMP_C2_STABTIME_Pos)) & CMP_C2_STABTIME_Msk)
#define CMP_C3_PRESET(x)            (((uint32_t)(((uint32_t)(x)) << CMP_C3_PRESET_Pos)) & CMP_C3_PRESET_Msk)
#define CMP_C4_DACVAL(x)            (((uint32_t)(((uint32_t)(x)) << CMP_C4_DACVAL_Pos)) & CMP_C4_DACVAL_Msk)
#define CMP_C5_POAS(x)              (((uint32_t)(((uint32_t)(x)) << CMP_C5_POAS_Pos)) & CMP_C5_POAS_Msk)
#define CMP_C5_POBS(x)              (((uint32_t)(((uint32_t)(x)) << CMP_C5_POBS_Pos)) & CMP_C5_POBS_Msk)
#define CMP_C5_POCS(x)              (((uint32_t)(((uint32_t)(x)) << CMP_C5_POCS_Pos)) & CMP_C5_POCS_Msk)
#define CMP_C5_PODS(x)              (((uint32_t)(((uint32_t)(x)) << CMP_C5_PODS_Pos)) & CMP_C5_PODS_Msk)

/*******APIs*******************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif

/*!
 * @brief Set the CMP output interrupts (rising edge, falling edge or both edges)
 *
 * @param[in] regBase: The CMP register base address
 * @param[in] edge: Comparator output edge interrupts configuration
 *            - CMP_FALL_EDGE_INT
 *            - CMP_RISE_EDGE_INT
 *            - CMP_BOTH_EDGE_INT
 * @return None
 */
static inline void CMP_REG_SetEdgeInt(CMP_Type* regBase, cmp_sensitive_edge_t edge)
{
    uint32_t regValue = regBase->C0;

    regValue &= ~(CMP_C0_EDGETYPE_Msk);
    regValue |= CMP_C0_EDGETYPE(edge);
    regBase->C0 = regValue;
}

/*!
 * @brief Get the CMP edge interrupt configuration
 *
 * @param[in] regBase: The CMP register base address
 * @return CMP edge interrupt configuration
 *         - CMP_FALL_EDGE_INT
 *         - CMP_RISE_EDGE_INT
 *         - CMP_BOTH_EDGE_INT
 */
static inline cmp_sensitive_edge_t CMP_REG_GetEdgeInt(CMP_Type* regBase)
{
    uint32_t regValue = regBase->C0;

    regValue = (regValue & CMP_C0_EDGETYPE_Msk) >> CMP_C0_EDGETYPE_Pos;

    return (cmp_sensitive_edge_t)(regValue);
}

/*!
 * @brief Set the CMP interrupt state
 *
 * @param[in] regBase: The CMP register base address
 * @param[in] enable: Interrupt state configuration
 *            - true: CMP interrupt is enabled
 *            - false: CMP interrupt is disabled
 * @return None
 */
static inline void CMP_REG_SetIntEnable(CMP_Type* regBase, bool enable)
{
    regBase->C0 = ((regBase->C0) & (~(CMP_C0_IE_Msk))) | ((uint32_t)enable << CMP_C0_IE_Pos);
}

/*!
 * @brief Get the CMP interrupt state
 *
 * @param[in] regBase: The CMP register base address
 * @return Interrupt state
 *         - true: CMP interrupt is enabled
 *         - false: CMP interrupt is disabled
 */
static inline bool CMP_REG_GetIntEnable(CMP_Type* regBase)
{
    return (bool)(((regBase->C0) >> CMP_C0_IE_Pos) & 1U);
}

/*!
 * @brief Set the CMP digital filter state
 *
 * @param[in] regBase: The CMP register base address
 * @param[in] enable: CMP digital filter state configuration
 *            - true: CMP digital filter is enabled
 *            - false: CMP digital filter is disabled
 * @return None
 */
static inline void CMP_REG_SetDigFilterEnable(CMP_Type* regBase, bool enable)
{
    regBase->C0 = ((regBase->C0) & (~(CMP_C0_FILTEREN_Msk))) | ((uint32_t)enable << CMP_C0_FILTEREN_Pos);
}

/*!
 * @brief Get the CMP digital filter state
 *
 * @param[in] regBase: The CMP register base address
 * @return CMP digital filter state configuration
 *         - true: CMP digital filter is enabled
 *         - false: CMP digital filter is disabled
 */
static inline bool CMP_REG_GetDigFilterEnable(CMP_Type* regBase)
{
    return (bool)(((regBase->C0) >> CMP_C0_FILTEREN_Pos) & 1U);
}

/*!
 * @brief Set the CMP digital filter clock divide
 *
 * @param[in] regBase: The CMP register base address
 * @param[in] div: Filter clock divide, 0-1023, correspond to (div + 1) clock divide
 * @return None
 */
static inline void CMP_REG_SetDigFilterClkDiv(CMP_Type* regBase, uint16_t div)
{
    uint32_t regValue = regBase->C6;

    regValue &= ~(CMP_C6_FILTERDIV_Msk);
    regValue |= CMP_C6_FILTERDIV(div);
    regBase->C6 = regValue;
}

/*!
 * @brief Get the CMP digital filter clock divide
 *
 * @param[in] regBase: The CMP register base address
 * @return Filter clock divide, 0-1023
 */
static inline uint16_t CMP_REG_GetDigFilterClkDiv(CMP_Type* regBase)
{
    uint32_t regValue = regBase->C6;

    regValue = (regValue & CMP_C6_FILTERDIV_Msk) >> CMP_C6_FILTERDIV_Pos;

    return (uint16_t)(regValue);
}

/*!
 * @brief Set the CMP digital filter width
 *
 * @param[in] regBase: The CMP register base address
 * @param[in] width: Filter width, 0-255
 * @return None
 */
static inline void CMP_REG_SetDigFilterWidth(CMP_Type* regBase, uint8_t width)
{
    uint32_t regValue = regBase->C6;

    regBase->C6 &= ~(CMP_C6_FILTERWIDTH_Msk);
    regValue &= ~(CMP_C6_FILTERWIDTH_Msk);
    regValue |= CMP_C6_FILTERWIDTH(width);
    regBase->C6 = regValue;
}

/*!
 * @brief Get the CMP digital filter width
 *
 * @param[in] regBase: The CMP register base address
 * @return Filter width, 0-255
 */
static inline uint8_t CMP_REG_GetDigFilterWidth(CMP_Type* regBase)
{
    uint32_t regValue = regBase->C6;

    regValue = (regValue & CMP_C6_FILTERWIDTH_Msk) >> CMP_C6_FILTERWIDTH_Pos;

    return (uint8_t)(regValue);
}

/*!
 * @brief Set the CMP output invert status
 *
 * @param[in] regBase: The CMP register base address
 * @param[in] status: CMP output invert configuration
 *            - true: CMP output is inverted
 *            - false: CMP output is  not inverted
 * @return None
 */
static inline void CMP_REG_SetInverterStatus(CMP_Type* regBase, bool enable)
{
    regBase->C0 = ((regBase->C0) & (~(CMP_C0_INV_Msk))) | ((uint32_t)enable << CMP_C0_INV_Pos);
}

/*!
 * @brief Get the CMP output invert status
 *
 * @param[in] regBase: The CMP register base address
 * @return CMP output invert configuration
 *         - true: CMP output is inverted
 *         - false: CMP output is  not inverted
 */
static inline bool CMP_REG_GetInverterStatus(CMP_Type* regBase)
{
    return (bool)(((regBase->C0) >> CMP_C0_INV_Pos) & 1U);
}

/*!
 * @brief Set the CMP output selcet
 *
 * @param[in] regBase: The CMP register base address
 * @param[in] select: CMP output selcet configuration
 *            - CMP_OUT_BEFORE_WINDOW : CMP_OUT is the output before window
 *            - CMP_OUT_AFTER_FILTER : CMP_OUT_FINAL is the output after filter
 * @return None
 */
static inline void CMP_REG_SetComparatorOutputSelect(CMP_Type* regBase, cmp_output_t select)
{
    regBase->C0 = ((regBase->C0) & (~(CMP_C0_COS_Msk))) | ((uint32_t)select << CMP_C0_COS_Pos);
}

/*!
 * @brief Get the CMP output selcet
 *
 * @param[in] regBase: The CMP register base address
 * @return CMP output selcet
 *         - CMP_OUT_BEFORE_WINDOW : CMP_OUT is the output before window
 *         - CMP_OUT_AFTER_FILTER : CMP_OUT_FINAL is the output after filter
 */
static inline cmp_output_t CMP_REG_GetComparatorOutputSelect(CMP_Type* regBase)
{
    return (cmp_output_t)(((regBase->C0) >> CMP_C0_COS_Pos) & 1U);
}

/*!
 * @brief Set the CMP output to pin status
 *
 * @param[in] regBase: The CMP register base address
 * @param[in] enable: CMP output to pin configuration
 *            - true: CMP output to pin is enabled
 *            - false: CMP output to pin is disabled
 * @return None
 */
static inline void CMP_REG_SetOutputPinStatus(CMP_Type* regBase, bool enable)
{
    regBase->C0 = ((regBase->C0) & (~(CMP_C0_CMPOUTPINEN_Msk))) | ((uint32_t)enable << CMP_C0_CMPOUTPINEN_Pos);
}

/*!
 * @brief Get the CMP output to pin status
 *
 * @param[in] regBase: The CMP register base address
 * @param[in] enable: CMP output to pin configuration
 * @return CMP output to pin status
 *         - true: CMP output to pin is enabled
 *         - false: CMP output to pin is disabled
 */
static inline bool CMP_REG_GetOutputPinStatus(CMP_Type* regBase)
{
    return (bool)(((regBase->C0) >> CMP_C0_CMPOUTPINEN_Pos) & 1U);
}

/*!
 * @brief Set the CMP window status
 *
 * @param[in] regBase: The CMP register base address
 * @param[in] enable: CMP window status configuration
 *            - true: CMP window is enabled
 *            - false: CMP window is disabled
 * @return None
 */
static inline void CMP_REG_SetWindowEnable(CMP_Type* regBase, bool enable)
{
    regBase->C0 = ((regBase->C0) & (~(CMP_C0_WINE_Msk))) | ((uint32_t)enable << CMP_C0_WINE_Pos);
}

/*!
 * @brief Get the CMP window status
 *
 * @param[in] regBase: The CMP register base address
 * @return CMP window status
 *         - true: CMP window is enabled
 *         - false: CMP window is disabled
 */
static inline bool CMP_REG_GetWindowEnable(CMP_Type* regBase)
{
    return (bool)(((regBase->C0) >> CMP_C0_WINE_Pos) & 1U);
}

/*!
 * @brief Set the CMP parallel output status
 *
 * @param[in] regBase: The CMP register base address
 * @param[in] enable: CMP parallel output status configuration
 *            - true: CMP parallel output is enabled
 *            - false: CMP parallel output is disabled
 * @return None
 */
static inline void CMP_REG_SetParallelOutputEnable(CMP_Type* regBase, bool enable)
{
    regBase->C0 = ((regBase->C0) & (~(CMP_C0_POE_Msk))) | ((uint32_t)enable << CMP_C0_POE_Pos);
}

/*!
 * @brief Get the CMP parallel output status
 *
 * @param[in] regBase: The CMP register base address
 * @return CMP parallel output status
 *         - true: CMP parallel output is enabled
 *         - false: CMP parallel output is disabled
 */
static inline bool CMP_REG_GetParallelOutputEnable(CMP_Type* regBase)
{
    return (bool)(((regBase->C0) >> CMP_C0_POE_Pos) & 1U);
}

/*!
 * @brief Set the CMP status
 *
 * @param[in] regBase: The CMP register base address
 * @param[in] enable: CMP status configuration
 *            - true: CMP module is enabled
 *            - false: CMP module is disabled
 * @return None
 */
static inline void CMP_REG_SetComparatorEnable(CMP_Type* regBase, bool enable)
{
    regBase->C0 = ((regBase->C0) & (~(CMP_C0_CMPEN_Msk))) | ((uint32_t)enable << CMP_C0_CMPEN_Pos);
}

/*!
 * @brief Get the CMP status
 *
 * @param[in] regBase: The CMP register base address
 * @return CMP status
 *         - true: CMP module is enabled
 *         - false: CMP module is disabled
 */
static inline bool CMP_REG_GetComparatorEnable(CMP_Type* regBase)
{
    return (bool)(((regBase->C0) >> CMP_C0_CMPEN_Pos) & 1U);
}

/*!
 * @brief Set the CMP hysterisis voltage
 *
 * @param[in] regBase: The CMP register base address
 * @param[in] hyst: CMP hysterisis voltage configuration
 *            - CMP_HYS_0MV
 *            - CMP_HYS_10MV
 *            - CMP_HYS_20MV
 *            - CMP_HYS_40MV
 * @return None
 */
static inline void CMP_REG_SetHysteresisVoltage(CMP_Type* regBase, cmp_hysteresis_t hyst)
{
    uint32_t regValue = regBase->C0;

    regValue &= ~(CMP_C0_HYSTSEL_Msk);
    regValue |= CMP_C0_HYSTSEL(hyst);
    regBase->C0 = regValue;
}

/*!
 * @brief Get the CMP hysterisis voltage
 *
 * @param[in] regBase: The CMP register base address
 * @return CMP hysterisis voltage
 *         - CMP_HYS_0MV
 *         - CMP_HYS_10MV
 *         - CMP_HYS_20MV
 *         - CMP_HYS_40MV
 */
static inline cmp_hysteresis_t CMP_REG_GetHysteresisVoltage(CMP_Type* regBase)
{
    uint32_t regValue = regBase->C0;

    regValue = (regValue & CMP_C0_HYSTSEL_Msk) >> CMP_C0_HYSTSEL_Pos;

    return (cmp_hysteresis_t)(regValue);
}

/*!
 * @brief Set the CMP loop mode operation mode
 *
 * @param[in] regBase: The CMP register base address
 * @param[in] loop: CMP loop port configuration
 *            - CMP_NO_LOOP
 *            - CMP_NEG_LOOP
 *            - CMP_POS_LOOP
 *            - CMP_NO_LOOP_1
 * @return None
 */
static inline void CMP_REG_SetLoopModeSelect(CMP_Type* regBase, cmp_loop_mode_t loop)
{
    uint32_t regValue = regBase->C1;

    regValue &= ~(CMP_C1_MODE_Msk);
    regValue |= CMP_C1_MODE(loop);
    regBase->C1 = regValue;
}

/*!
 * @brief Get the CMP loop mode operation mode
 *
 * @param[in] regBase: The CMP register base address
 * @return CMP loop port operation mode
 *         - CMP_NO_LOOP
 *         - CMP_NEG_LOOP
 *         - CMP_POS_LOOP
 *         - CMP_NO_LOOP_1
 */
static inline cmp_loop_mode_t CMP_REG_GetLoopModeSelect(CMP_Type* regBase)
{
    uint32_t regValue = regBase->C1;

    regValue = (regValue & CMP_C1_MODE_Msk) >> CMP_C1_MODE_Pos;

    return (cmp_loop_mode_t)(regValue);
}

/*!
 * @brief Set the CMP negative port input
 *
 * @param[in] regBase: The CMP register base address
 * @param[in] neg: CMP negative port input configuration
 *            - CMP_EXTERNAL_CH0
 *            - CMP_EXTERNAL_CH1
 *            - CMP_EXTERNAL_CH2
 *            - CMP_EXTERNAL_CH3
 *            - CMP_EXTERNAL_CH4
 *            - CMP_EXTERNAL_CH5
 *            - CMP_EXTERNAL_CH6
 *            - CMP_EXTERNAL_CH7
 *            - CMP_DAC_OUTPUT
 *            - BG_VOLTAGE
 * @return None
 */
static inline void CMP_REG_SetNegPortInput(CMP_Type* regBase, cmp_channel_select_t neg)
{
    uint32_t regValue = regBase->C1;

    regValue &= ~(CMP_C1_INNSEL_Msk);
    regValue |= CMP_C1_INNSEL(neg);
    regBase->C1 = regValue;
}

/*!
 * @brief Get the CMP negative port input
 *
 * @param[in] regBase: The CMP register base address
 * @return CMP negative port input
 *         - CMP_EXTERNAL_CH0
 *         - CMP_EXTERNAL_CH1
 *         - CMP_EXTERNAL_CH2
 *         - CMP_EXTERNAL_CH3
 *         - CMP_EXTERNAL_CH4
 *         - CMP_EXTERNAL_CH5
 *         - CMP_EXTERNAL_CH6
 *         - CMP_EXTERNAL_CH7
 *         - CMP_DAC_OUTPUT
 *         - BG_VOLTAGE
 */
static inline cmp_channel_select_t CMP_REG_GetNegPortInput(CMP_Type* regBase)
{
    uint32_t regValue = regBase->C1;

    regValue = (regValue & CMP_C1_INNSEL_Msk) >> CMP_C1_INNSEL_Pos;

    return (cmp_channel_select_t)(regValue);
}

/*!
 * @brief Set the CMP positive port input
 *
 * @param[in] regBase: The CMP register base address
 * @param[in] neg: CMP positive port input configuration
 *            - CMP_EXTERNAL_CH0
 *            - CMP_EXTERNAL_CH1
 *            - CMP_EXTERNAL_CH2
 *            - CMP_EXTERNAL_CH3
 *            - CMP_EXTERNAL_CH4
 *            - CMP_EXTERNAL_CH5
 *            - CMP_EXTERNAL_CH6
 *            - CMP_EXTERNAL_CH7
 *            - CMP_DAC_OUTPUT
 *            - BG_VOLTAGE
 * @return None
 */
static inline void CMP_REG_SetPosPortInput(CMP_Type* regBase, cmp_channel_select_t pos)
{
    uint32_t regValue = regBase->C1;

    regValue &= ~(CMP_C1_INPSEL_Msk);
    regValue |= CMP_C1_INPSEL(pos);
    regBase->C1 = regValue;
}

/*!
 * @brief Get the CMP positive port input
 *
 * @param[in] regBase: The CMP register base address
 * @return CMP positive port input
 *         - CMP_EXTERNAL_CH0
 *         - CMP_EXTERNAL_CH1
 *         - CMP_EXTERNAL_CH2
 *         - CMP_EXTERNAL_CH3
 *         - CMP_EXTERNAL_CH4
 *         - CMP_EXTERNAL_CH5
 *         - CMP_EXTERNAL_CH6
 *         - CMP_EXTERNAL_CH7
 *         - CMP_DAC_OUTPUT
 *         - BG_VOLTAGE
 */
static inline cmp_channel_select_t CMP_REG_GetPosPortInput(CMP_Type* regBase)
{
    uint32_t regValue = regBase->C1;

    regValue = (regValue & CMP_C1_INPSEL_Msk) >> CMP_C1_INPSEL_Pos;

    return (cmp_channel_select_t)(regValue);
}

/*!
 * @brief Set the CMP loop sequence
 *
 * @param[in] regBase: The CMP register base address
 * @param[in] seq: CMP loop sequence configuration, 0-511(0x1FF)
 * @return None
 */
static inline void CMP_REG_SetLoopSequence(CMP_Type* regBase, uint16_t seq)
{
    uint32_t regValue = regBase->C1;

    regValue &= ~(CMP_LOOP_SEQUENCE_Msk);
    regValue |= CMP_C1_LOOPCH(seq);
    regBase->C1 = regValue;
}

/*!
 * @brief Get the CMP loop sequence
 *
 * @param[in] regBase: The CMP register base address
 * @return CMP loop sequence, 0-511(0x1FF)
 */
static inline uint16_t CMP_REG_GetLoopSequence(CMP_Type* regBase)
{
    uint32_t regValue = regBase->C1;

    regValue = (regValue & (uint32_t)CMP_LOOP_SEQUENCE_Msk) >> CMP_LOOP_SEQUENCE_Pos;

    return (uint16_t)(regValue);
}

/*!
 * @brief Set the CMP loop frequence clock divide
 *
 * @param[in] regBase: The CMP register base address
 * @param[in] div: CMP loop frequence clock divide configuration, 0-65535(0xFFFF)
 * @return None
 */
static inline void CMP_REG_SetLoopFreqDivide(CMP_Type* regBase, uint16_t div)
{
    uint32_t regValue = regBase->C2;

    regValue &= ~(CMP_C2_LMSCNT_Msk);
    regValue |= CMP_C2_LMSCNT(div);
    regBase->C2 = regValue;
}

/*!
 * @brief Get the CMP loop frequence clock divide
 *
 * @param[in] regBase: The CMP register base address
 * @return CMP loop frequence clock divide, 0-65535(0xFFFF)
 */
static inline uint16_t CMP_REG_GetLoopFreqDivide(CMP_Type* regBase)
{
    uint32_t regValue = regBase->C2;

    regValue = (regValue & (uint32_t)CMP_C2_LMSCNT_Msk) >> CMP_C2_LMSCNT_Pos;

    return (uint16_t)(regValue);
}

/*!
 * @brief Set the CMP channele switch and CMP enable initial delay time
 *
 * @param[in] regBase: The CMP register base address
 * @param[in] delay: CMP channele switch and enable initial delay time configuration, 0-255(0xFF)
 * @return None
 */
static inline void CMP_REG_SetInitDelay(CMP_Type* regBase, uint8_t delay)
{
    uint32_t regValue = regBase->C2;

    regValue &= ~(CMP_C2_STABTIME_Msk);
    regValue |= CMP_C2_STABTIME(delay);
    regBase->C2 = regValue;
}

/*!
 * @brief Get the CMP channele switch and enable initial delay time
 *
 * @param[in] regBase: The CMP register base address
 * @return CMP channele switch and enable initial delay time, 0-255(0xFF)
 */
static inline uint8_t CMP_REG_GetInitDelay(CMP_Type* regBase)
{
    uint32_t regValue = regBase->C2;

    regValue = (regValue & CMP_C2_STABTIME_Msk) >> CMP_C2_STABTIME_Pos;

    return (uint8_t)(regValue);
}

/*!
 * @brief Set the CMP channele pre-set state
 *
 * @param[in] regBase: The CMP register base address
 * @param[in] preset: CMP loop channele pre-set state configuration, 0-1023(0x3FF)
 * @return None
 */
static inline void CMP_REG_SetChPresetState(CMP_Type* regBase, uint16_t preset)
{
    uint32_t regValue = regBase->C3;

    regValue &= ~(CMP_C3_PRESET_Msk);
    regValue |= CMP_C3_PRESET(preset);
    regBase->C3 = regValue;
}

/*!
 * @brief Get the CMP channele pre-set state
 *
 * @param[in] regBase: The CMP register base address
 * @return CMP loop channele pre-set state, 0-1023(0x3FF)
 */
static inline uint16_t CMP_REG_GetChPresetState(CMP_Type* regBase)
{
    uint32_t regValue = regBase->C3;

    regValue = (regValue & CMP_C3_PRESET_Msk) >> CMP_C3_PRESET_Pos;

    return (uint16_t)(regValue);
}

/*!
 * @brief Set the DAC state
 *
 * @param[in] regBase: The CMP register base address
 * @param[in] enable: DAC state configuration
 *            - true: DAC is enabled
 *            - false: DAC is disabled
 * @return None
 */
static inline void CMP_REG_SetDacEnable(CMP_Type* regBase, bool enable)
{
    regBase->C4 = ((regBase->C4) & (~(CMP_C4_DACEN_Msk))) | ((uint32_t)enable << CMP_C4_DACEN_Pos);
}

/*!
 * @brief Get the DAC state
 *
 * @param[in] regBase: The CMP register base address
 * @return DAC state
 *         - true: DAC is enabled
 *         - false: DAC is disabled
 * @return None
 */
static inline bool CMP_REG_GetDacEnable(CMP_Type* regBase)
{
    return (bool)(((regBase->C4) >> CMP_C4_DACEN_Pos) & 1U);
}

/*!
 * @brief Set the DAC volatge reference source
 *
 * @param[in] regBase: The CMP register base address
 * @param[in] ref: DAC volatge reference source configuration
 *            - CMP_DAC_BANDGAP
 *            - CMP_DAC_VDD
 * @return None
 */
static inline void CMP_REG_SetDacVoltRef(CMP_Type* regBase, cmp_dac_volt_reference_t ref)
{
    regBase->C4 = ((regBase->C4) & (~(CMP_C4_DACREF_Msk))) | ((uint32_t)ref << CMP_C4_DACREF_Pos);
}

/*!
 * @brief Get the DAC volatge reference source
 *
 * @param[in] regBase: The CMP register base address
 * @return DAC volatge reference source
 *         - CMP_DAC_BANDGAP
 *         - CMP_DAC_VDD
 */
static inline cmp_dac_volt_reference_t CMP_REG_GetDacVoltRef(CMP_Type* regBase)
{
    return (cmp_dac_volt_reference_t)(((regBase->C4) >> CMP_C4_DACREF_Pos) & 1U);
}

/*!
 * @brief Set the DAC volatge value
 *
 * @param[in] regBase: The CMP register base address
 * @param[in] volt: DAC volatge value, 0-255(0xFF)
 * @return None
 */
static inline void CMP_REG_SetDacVoltValue(CMP_Type* regBase, uint8_t volt)
{
    uint32_t regValue = regBase->C4;

    regValue &= ~(CMP_C4_DACVAL_Msk);
    regValue |= CMP_C4_DACVAL(volt);
    regBase->C4 = regValue;
}

/*!
 * @brief Get the DAC volatge value
 *
 * @param[in] regBase: The CMP register base address
 * @return DAC volatge value, 0-255(0xFF)
 */
static inline uint8_t CMP_REG_GetDacVoltValue(CMP_Type* regBase)
{
    uint32_t regValue = regBase->C4;

    regValue = (regValue & CMP_C4_DACVAL_Msk) >> CMP_C4_DACVAL_Pos;

    return (uint8_t)(regValue);
}

/*!
 * @brief Set the DAC output to pin state
 *
 * @param[in] regBase: The CMP register base address
 * @param[in] enable: DAC state configuration
 *            - true: DAC output to pin is enabled
 *            - false: DAC output to pin is disabled
 * @return None
 */
static inline void CMP_REG_SetDacPinEnable(CMP_Type* regBase, bool enable)
{
    regBase->C4 = ((regBase->C4) & (~(CMP_C4_DACPINEN_Msk))) | ((uint32_t)enable << CMP_C4_DACPINEN_Pos);
}

/*!
 * @brief Get the DAC output to pin state
 *
 * @param[in] regBase: The CMP register base address
 * @return DAC state
 *         - true: DAC output to pin is enabled
 *         - false: DAC output to pin is disabled
 * @return None
 */
static inline bool CMP_REG_GetDacPinEnable(CMP_Type* regBase)
{
    return (bool)(((regBase->C4) >> CMP_C4_DACPINEN_Pos) & 1U);
}

/*!
 * @brief Set the CMP parallel output A select
 *
 * @param[in] regBase: The CMP register base address
 * @param[in] poa: CMP parallel output A configuration
 *            - CMP_EXTERNAL_CH0
 *            - CMP_EXTERNAL_CH1
 *            - CMP_EXTERNAL_CH2
 *            - CMP_EXTERNAL_CH3
 *            - CMP_EXTERNAL_CH4
 *            - CMP_EXTERNAL_CH5
 *            - CMP_EXTERNAL_CH6
 *            - CMP_EXTERNAL_CH7
 *            - CMP_EXTERNAL_CH8(CMP_DAC_OUTPUT)
 *            - BG_VOLTAGE
 * @return None
 */
static inline void CMP_REG_SetParallelOutputASelect(CMP_Type* regBase, cmp_channel_select_t poa)
{
    uint32_t regValue = regBase->C5;

    regValue &= ~(CMP_C5_POAS_Msk);
    regValue |= CMP_C5_POAS(poa);
    regBase->C5 = regValue;
}

/*!
 * @brief Get the CMP parallel output A select
 *
 * @param[in] regBase: The CMP register base address
 * @return CMP parallel output A
 *         - CMP_EXTERNAL_CH0
 *         - CMP_EXTERNAL_CH1
 *         - CMP_EXTERNAL_CH2
 *         - CMP_EXTERNAL_CH3
 *         - CMP_EXTERNAL_CH4
 *         - CMP_EXTERNAL_CH5
 *         - CMP_EXTERNAL_CH6
 *         - CMP_EXTERNAL_CH7
 *         - CMP_EXTERNAL_CH8(CMP_DAC_OUTPUT)
 *         - BG_VOLTAGE
 */
static inline cmp_channel_select_t CMP_REG_GetParallelOutputASelect(CMP_Type* regBase)
{
    uint32_t regValue = regBase->C5;

    regValue = (regValue & CMP_C5_POAS_Msk) >> CMP_C5_POAS_Pos;

    return (cmp_channel_select_t)(regValue);
}

/*!
 * @brief Set the CMP parallel output B select
 *
 * @param[in] regBase: The CMP register base address
 * @param[in] pob: CMP parallel output B configuration
 *            - CMP_EXTERNAL_CH0
 *            - CMP_EXTERNAL_CH1
 *            - CMP_EXTERNAL_CH2
 *            - CMP_EXTERNAL_CH3
 *            - CMP_EXTERNAL_CH4
 *            - CMP_EXTERNAL_CH5
 *            - CMP_EXTERNAL_CH6
 *            - CMP_EXTERNAL_CH7
 *            - CMP_EXTERNAL_CH8(CMP_DAC_OUTPUT)
 *            - BG_VOLTAGE
 * @return None
 */
static inline void CMP_REG_SetParallelOutputBSelect(CMP_Type* regBase, cmp_channel_select_t pob)
{
    uint32_t regValue = regBase->C5;

    regValue &= ~(CMP_C5_POBS_Msk);
    regValue |= CMP_C5_POBS(pob);
    regBase->C5 = regValue;
}

/*!
 * @brief Get the CMP parallel output B select
 *
 * @param[in] regBase: The CMP register base address
 * @return CMP parallel output B
 *         - CMP_EXTERNAL_CH0
 *         - CMP_EXTERNAL_CH1
 *         - CMP_EXTERNAL_CH2
 *         - CMP_EXTERNAL_CH3
 *         - CMP_EXTERNAL_CH4
 *         - CMP_EXTERNAL_CH5
 *         - CMP_EXTERNAL_CH6
 *         - CMP_EXTERNAL_CH7
 *         - CMP_EXTERNAL_CH8(CMP_DAC_OUTPUT)
 *         - BG_VOLTAGE
 */
static inline cmp_channel_select_t CMP_REG_GetParallelOutputBSelect(CMP_Type* regBase)
{
    uint32_t regValue = regBase->C5;

    regValue = (regValue & CMP_C5_POBS_Msk) >> CMP_C5_POBS_Pos;

    return (cmp_channel_select_t)(regValue);
}

/*!
 * @brief Set the CMP parallel output C select
 *
 * @param[in] regBase: The CMP register base address
 * @param[in] poc: CMP parallel output C configuration
 *            - CMP_EXTERNAL_CH0
 *            - CMP_EXTERNAL_CH1
 *            - CMP_EXTERNAL_CH2
 *            - CMP_EXTERNAL_CH3
 *            - CMP_EXTERNAL_CH4
 *            - CMP_EXTERNAL_CH5
 *            - CMP_EXTERNAL_CH6
 *            - CMP_EXTERNAL_CH7
 *            - CMP_EXTERNAL_CH8(CMP_DAC_OUTPUT)
 *            - BG_VOLTAGE
 * @return None
 */
static inline void CMP_REG_SetParallelOutputCSelect(CMP_Type* regBase, cmp_channel_select_t poc)
{
    uint32_t regValue = regBase->C5;

    regValue &= ~(CMP_C5_POCS_Msk);
    regValue |= CMP_C5_POCS(poc);
    regBase->C5 = regValue;
}

/*!
 * @brief Get the CMP parallel output C select
 *
 * @param[in] regBase: The CMP register base address
 * @return CMP parallel output C
 *         - CMP_EXTERNAL_CH0
 *         - CMP_EXTERNAL_CH1
 *         - CMP_EXTERNAL_CH2
 *         - CMP_EXTERNAL_CH3
 *         - CMP_EXTERNAL_CH4
 *         - CMP_EXTERNAL_CH5
 *         - CMP_EXTERNAL_CH6
 *         - CMP_EXTERNAL_CH7
 *         - CMP_EXTERNAL_CH8(CMP_DAC_OUTPUT)
 *         - BG_VOLTAGE
 */
static inline cmp_channel_select_t CMP_REG_GetParallelOutputCSelect(CMP_Type* regBase)
{
    uint32_t regValue = regBase->C5;

    regValue = (regValue & CMP_C5_POCS_Msk) >> CMP_C5_POCS_Pos;

    return (cmp_channel_select_t)(regValue);
}

/*!
 * @brief Set the CMP parallel output D select
 *
 * @param[in] regBase: The CMP register base address
 * @param[in] pod: CMP parallel output D configuration
 *            - CMP_EXTERNAL_CH0
 *            - CMP_EXTERNAL_CH1
 *            - CMP_EXTERNAL_CH2
 *            - CMP_EXTERNAL_CH3
 *            - CMP_EXTERNAL_CH4
 *            - CMP_EXTERNAL_CH5
 *            - CMP_EXTERNAL_CH6
 *            - CMP_EXTERNAL_CH7
 *            - CMP_EXTERNAL_CH8(CMP_DAC_OUTPUT)
 *            - BG_VOLTAGE
 * @return None
 */
static inline void CMP_REG_SetParallelOutputDSelect(CMP_Type* regBase, cmp_channel_select_t pod)
{
    uint32_t regValue = regBase->C5;

    regValue &= ~(CMP_C5_PODS_Msk);
    regValue |= CMP_C5_PODS(pod);
    regBase->C5 = regValue;
}

/*!
 * @brief Get the CMP parallel output D select
 *
 * @param[in] regBase: The CMP register base address
 * @return CMP parallel output D
 *         - CMP_EXTERNAL_CH0
 *         - CMP_EXTERNAL_CH1
 *         - CMP_EXTERNAL_CH2
 *         - CMP_EXTERNAL_CH3
 *         - CMP_EXTERNAL_CH4
 *         - CMP_EXTERNAL_CH5
 *         - CMP_EXTERNAL_CH6
 *         - CMP_EXTERNAL_CH7
 *         - CMP_EXTERNAL_CH8(CMP_DAC_OUTPUT)
 *         - BG_VOLTAGE
 */
static inline cmp_channel_select_t CMP_REG_GetParallelOutputDSelect(CMP_Type* regBase)
{
    uint32_t regValue = regBase->C5;

    regValue = (regValue & CMP_C5_PODS_Msk) >> CMP_C5_PODS_Pos;

    return (cmp_channel_select_t)(regValue);
}

/*!
 * @brief Get the CMP loop mode output result
 *
 * @param[in] regBase: The CMP register base address
 * @return CMP loop mode output result, 0-511(0x1FF)
 */
static inline uint16_t CMP_REG_GetLoopModeOutput(CMP_Type* regBase)
{
    uint32_t regValue = regBase->DR;

    regValue = (regValue & CMP_DR_LMCHO_Msk) >> CMP_DR_LMCHO_Pos;

    return (uint16_t)(regValue);
}

/*!
 * @brief Get the CMP normal mode output result
 *
 * @param[in] regBase: The CMP register base address
 * @return CMP normal mode output result, 0-1
 */
static inline uint8_t CMP_REG_GetNormalModeOutput(CMP_Type* regBase)
{
    return (uint8_t)(((regBase->DR) >> CMP_DR_NMCO_Pos) & 1U);
}

/*!
 * @brief Get the CMP loop mode and normal mode interrupt flags
 *
 * @param[in] regBase: The CMP register base address
 * @return CMP interrupt flags, 0-1023(0x3FF)
 */
static inline uint16_t CMP_REG_GetIntFlags(CMP_Type* regBase)
{
    uint32_t regValue = regBase->SR;

    regValue = (regValue & (uint32_t)CMP_SR_IRQFLAG_Msk) >> CMP_SR_IRQFLAG_Pos;

    return (uint16_t)(regValue);
}

/*!
 * @brief Clear the CMP loop mode and normal mode interrupt flags
 *
 * @param[in] regBase: The CMP register base address
 * @return None
 */
static inline void CMP_REG_ClrIntFlags(CMP_Type* regBase)
{
    uint32_t regValue = regBase->SR;

    regValue |= (uint32_t)CMP_SR_IRQFLAG_Msk;
    regBase->SR = regValue;
}

/*!
 * @brief Get the CMP output result ready flag
 *
 * @param[in] regBase: The CMP register base address
 * @return CMP output result ready flag
 *         - 0: CMP output result is not ready
 *         - 1: CMP output result is ready
 */
static inline uint8_t CMP_REG_GetOutReadyFlag(CMP_Type* regBase)
{
    return (uint8_t)(((regBase->SR) >> CMP_SR_READY_Pos) & 1U);
}

#if defined(__cplusplus)
}
#endif

#endif /* CMP_REG_ACCESS_H */

/*******EOF********************************************************************/
